package generic;

/**
 * @author ChangLiang
 * @date 2021/2/1
 */
interface FactoryI<T> {
    T create();
}

class Foo2<T> {
    private T x;

    /**
     * 与InstantiateGenericType相比 这确实只是传递Class<T>的一种变体。
     * 两种方式都传递了工厂对象， 在InstantiateGenericType中Class<T>碰巧是内建的工厂对象，
     * 而FactoryConstraint的方式创建了一个显式的工厂对象，但是你却获得了编译期检查。
     * @param factory
     * @param <F>
     */
    public <F extends FactoryI<T>> Foo2(F factory) {
        x = factory.create();
    }
    // ...
}

class IntegerFactory implements FactoryI<Integer> {
    @Override
    public Integer create() {
        return new Integer(0);
    }
}

class Widget {
    public static class Factory implements FactoryI<Widget> {
        @Override
        public Widget create() {
            return new Widget();
        }
    }
}

public class FactoryConstraint {
    public static void main(String[] args) {

        new Foo2<>(new IntegerFactory());

        new Foo2<>(new Widget.Factory());
    }
}
